package com.dataextend.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dataextend.Enum.TagCodeEnum;
import com.dataextend.Enum.TrackingEnum;
import com.dataextend.entity.EventAnalysisRequest;
import com.dataextend.mapper.master.ClickhouseMapper;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 *  Clickhouse 事件分析模型
 */
@Service
public class ClickhouseEventAnalysisService {
    @Autowired
    ClickhouseMapper clickhouseMapper;


    /***
     *  主要计算函数
     */
    private JSONArray eventAnalysis(String startDate, String endDate, String eventCode, String countType, List<JSONObject> filterParameter, List<String> target){
        JSONArray returnResult = new JSONArray();
        String countCalculate = null;
        if (countType.equals("次数")){
            countCalculate = "count(*) as num ";
        } else {
            countCalculate = "count(distinct distinct_id) as num ";
        }

        StringBuilder targetDimension =  new StringBuilder();
        String targetCondition = null;
        String groupCondition = null;
        String orderCondition = null;
        StringBuilder concatCondition = new StringBuilder();
        String concatCondition_ = null;
        // 如果有指标的话,需要进行分组
        if (target.size()>0){
            for (String obj : target){
                String save = obj + ",";
                String concat = obj + ", ',' ,";
                targetDimension.append(save);
                concatCondition.append(concat);
            }
            if (target.size()>1){
                concatCondition_ = "CONCAT(" + concatCondition.toString().substring(0, concatCondition.toString().length()-7) + ") as logo,";
                targetCondition = targetDimension.toString();
                groupCondition = " group by datadate," + targetDimension.toString().substring(0, targetDimension.toString().length()-1) + "," +concatCondition_.substring(0, concatCondition_.length()-9);
                orderCondition = " order by datadate," + targetDimension.toString().substring(0, targetDimension.toString().length()-1) + "," +concatCondition_.substring(0, concatCondition_.length()-9);
            } else {
                concatCondition_ = "";
                targetCondition = targetDimension.toString();
                groupCondition = " group by datadate," + targetDimension.toString().substring(0, targetDimension.toString().length()-1);
                orderCondition = " order by datadate," + targetDimension.toString().substring(0, targetDimension.toString().length()-1);
            }

                    } else {
            concatCondition_ = "";
            targetCondition = "";
            groupCondition = " group by datadate";
            orderCondition = " order by datadate";
        }

        String str_1 = "select datadate," + targetCondition + concatCondition_ + countCalculate + " from userprofile_analysis_model ";
        String str_2 = "where datadate >= '" + startDate + "'" + " and datadate <='" + endDate + "'" + " and clickevent ='" + eventCode + "'";;
        String str_first = null;
        String condition = null;
        StringBuilder permission = new StringBuilder();
        if (filterParameter.size()>0){
            for (JSONObject obj : filterParameter){
                String type = obj.getString("type");
                String field = obj.getString("field");
                String name = obj.getString("name");
                String tag = obj.getString("tag");
                if (type.equals("event")){
                    condition = " and (" + field + "='" + tag + "')";
                    permission.append(condition);

                } else {
                    String fieldName = "tag_" + field;
                    condition = " and (" + fieldName + "='" + tag + "')";
                    permission.append(condition);
                }
            }
            str_first = str_1 + str_2 + permission.toString();
        } else {
            str_first = str_1 + str_2;
        }

        String str_final = str_first + groupCondition + orderCondition;
//        System.out.println("---查询sql语句:" + str_final);   // 打印拼接的SQL

        List<JSONObject> searchResult = clickhouseMapper.eventAnalysis(str_final);
//        System.out.println("--------------sql: " + searchResult);     // 打印查询的结果

//        -----------------------------------------------------------------------------------------------
        List<String> allGroup = new ArrayList<>();
        if (target.size()>1) {
            allGroup = groupName(searchResult, "1");        // 多个分组,所有分组的名称
        } else if (target.size()==1){
            allGroup = groupName(searchResult, target.get(0));        // 只有一个分组,所有分组的名称
        }

        if (target.size() >= 1){           // 有分组时的返回
            for (String groupId : allGroup){
                JSONObject mergeResult = new JSONObject();
                List<Long> saveValue = new ArrayList<>();
                for (JSONObject obj : searchResult){
                    String key = null;
                    if (target.size()>1) {
                        key = obj.getString("logo");
                    }else if (target.size()==1){
                        key = obj.getString(target.get(0));
                    }

                    if (key.equals(groupId)){
                        saveValue.add(obj.getLongValue("num"));
                    }
                }
                mergeResult.put("legend", parseCode(groupId));   // 解析为中文
                mergeResult.put("value", saveValue);
                mergeResult.put("total", saveValue.stream().reduce(Long::sum).orElse(0L));
                returnResult.add(mergeResult);
//                System.out.println("--------------mergeResult: " + mergeResult);
            }

        } else {                      // 没有分组时的返回
            JSONObject mergeResult = new JSONObject();
            List<Long> saveValue = new ArrayList<>();
            for (JSONObject obj : searchResult){
                saveValue.add(obj.getLongValue("num"));
            }
            mergeResult.put("legend", "");
            mergeResult.put("value", saveValue);
            mergeResult.put("total", saveValue.stream().reduce(Long::sum).orElse(0L));
            returnResult.add(mergeResult);
        }


        return returnResult;
    }



    /***
     *  解析标签code
     */
    private String parseCode(String groupId){
        if (StringUtils.isEmpty(groupId)){  // 如果是空的直接返回
            return groupId;
        } else {
            if (groupId.contains(",")){   // 有多个分组
                StringBuilder groupNames = new StringBuilder();
                String[] charNames = groupId.split(",");   // 将字符串切割成数组
                for (String charName :charNames){
                    String aa = null;
                    if (charName.contains("_")){           // 如果包含标签code
                        aa = TagCodeEnum.getName(charName) + ",";
                        groupNames.append(aa);
                    } else {
                        aa = charName + ",";
                        groupNames.append(aa);
                    }
                }

                return groupNames.toString().substring(0, groupNames.toString().length()-1);

            } else {    // 只有一个分组
                if (groupId.contains("_")){     // 包含code
                    return TagCodeEnum.getName(groupId);
                } else {
                    return groupId;
                }
            }
        }

    }



    /***
     *  计算包含的分组
     */
    private List<String> groupName(List<JSONObject> searchResult, String type){
        List<String> allGroup = new ArrayList<>();
        for (JSONObject obj :searchResult){
            if (type.equals("1")){
                allGroup.add(obj.getString("logo"));
            } else {
                allGroup.add(obj.getString(type));
            }
        }
        return allGroup.stream().distinct().collect(Collectors.toList());
    }



    // 解析日期从String到Long
    private long parseDateToLong (String dataDate){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        try {
            long dateTime = simpleDateFormat.parse(dataDate).getTime();
            return dateTime;
        } catch (Exception e){
            e.printStackTrace();
        }
        return 0L;
    }


    /**
     *  请求返回函数
     */
    public JSONObject findCount(EventAnalysisRequest eventAnalysisRequest){
        List<JSONObject> eventCodes = eventAnalysisRequest.getEventCodes();
        JSONArray detailAll = new JSONArray();
        JSONObject returnResult = new JSONObject(true);
        JSONArray detailResult = new JSONArray();   // 每个行为事件查询的结果明细
        for (JSONObject obj : eventCodes){
            JSONObject eventResult = new JSONObject(true);
            String eventCode = obj.getString("eventCode");
            String countType = obj.getString("countType");
            detailResult = eventAnalysis(eventAnalysisRequest.getStartDate(), eventAnalysisRequest.getEndDate(), eventCode, countType,
                    eventAnalysisRequest.getFilterParameter(), eventAnalysisRequest.getTarget());
            System.out.println("-----------returnResult:" + detailResult);

//            eventResult.put(eventCode, detailResult);
            String targetName = TrackingEnum.getName(eventCode) + "的" + countType;
            eventResult.put(targetName, detailResult);
            detailAll.add(eventResult);
        }

        returnResult.put("all", detailAll);   // 所有查询的结果明细

        // 存储起止日期
        List<String> dataList = new ArrayList<>();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        long startDate = parseDateToLong(eventAnalysisRequest.getStartDate());
        long endDate = parseDateToLong(eventAnalysisRequest.getEndDate());
        for (long i = startDate; i<=endDate; i+=86400000) {
            String dataDate = simpleDateFormat.format(new Date(i));
            dataList.add(dataDate);
        }
        returnResult.put("dataList", dataList);   // 所有查询的结果明细

        System.out.println("-----------dataList:" + dataList);
        return returnResult;
    }


}
